package com.suny.single_thread_execution.semaphore;

import java.util.Random;
import java.util.concurrent.Semaphore;

public class BoundeResource {
    private final Semaphore semaphore;
    private final int permits;
    private final Random random = new Random(314159);

    /**
     * permits为资源个数
     */
    public BoundeResource(int permits) {
        this.semaphore = new Semaphore(permits);
        this.permits = permits;
    }

    /**
     * 使用资源
     * acquire： 是否确实存在可用资源。当所有资源都已被使用时，线程会阻塞在该方法中。
     *           当线程从acquire返回时，则一定存在可用资源。
     * release： 释放资源
     *
     * @throws InterruptedException
     */
    public void use() throws InterruptedException {
        semaphore.acquire();
        try {
            doUse();
        } finally {
            semaphore.release();
        }
    }

    /**
     * 实际使用资源
     * @throws InterruptedException
     */
    protected void doUse() throws InterruptedException {
        Log.println("BEGIN: used = " + (permits - semaphore.availablePermits()));
        Thread.sleep(random.nextInt(500));
        Log.println("END: used = " + (permits - semaphore.availablePermits()));
    }
}
